/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * Projects
 * Copyright (C) Arnaud Duval 2010 <arnaud.duval@gmail.com>
 * 
 * Projects is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Projects is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "rgb-color.hpp"
#include <cassert>

///@brief Constructor
RGBcolor::RGBcolor()
{
	red = 0.;
	green = 0.;
	blue = 0.;
}

///@brief Constructor with arguments
///@param Dred red value
///@param Dgreen green value
///@param Dblue blue value
RGBcolor::RGBcolor(double Dred, double Dgreen, double Dblue)
{
	assert((Dred >= 0.)&&(Dred <= 1.));
	assert((Dgreen >= 0.)&&(Dgreen <= 1.));
	assert((Dblue >= 0.)&&(Dblue <= 1.));
	red = Dred;
	green = Dgreen;
	blue = Dblue;
}

///@brief Copy conctructor
///@param c RGBcolor object to copy
RGBcolor::RGBcolor(const RGBcolor& c)
{
	red = c.red;
	green = c.green;
	blue = c.blue;
}

///@brief Destructor
RGBcolor::~RGBcolor()
{

}

///@brief Overload of = operator
///@param c right hand operand
RGBcolor& RGBcolor::operator=(const RGBcolor &c)
{
	red = c.red;
	green = c.green;
	blue = c.blue;
	return (*this);
}

///@brief Return red value
double RGBcolor::Red()
{
	return red;
}

///@brief Return green value
double RGBcolor::Green()
{
	return green;
}

///@brief Return blue value
double RGBcolor::Blue()
{
	return blue;
}

///@brief Set red value
///@param Dred red value to be set
void RGBcolor::SetRed(double Dred)
{
	assert((Dred >= 0.)&&(Dred <= 1.));
	red = Dred;
}

///@brief Set green value
///@param Dgreen green value to be set
void RGBcolor::SetGreen(double Dgreen)
{
	assert((Dgreen >= 0.)&&(Dgreen <= 1.));
	green = Dgreen;
}

///@brief Set blue value
///@param Dblue blue value to be set
void RGBcolor::SetBlue(double Dblue)
{
	assert((Dblue >= 0.)&&(Dblue <= 1.));
	green = Dblue;
}

///@brief Set the color with predefined value
///@param value Predefined color value
void RGBcolor::SetPredefined(unsigned int value)
{
	switch(value)
	{
		case RED_COLOR:
		{
			red = 1.;
			green = 0.;
			blue = 0.;
			break;
		}
		case BLUE_COLOR:
		{
			red = 0.;
			green = 0.;
			blue = 1.;
			break;
		}
		case GREEN_COLOR:
		{
			red = 0.;
			green = 1.;
			blue = 0.;
			break;
		}
		case BLACK_COLOR:
		{
			red = 0.;
			green = 0.;
			blue = 0.;
			break;
		}
		case WHITE_COLOR:
		{
			red = 1.;
			green = 1.;
			blue = 1.;
			break;
		}
		case YELLOW_COLOR:
		{
			red = 1.;
			green = 1.;
			blue = 0.;
			break;
		}
		case ORANGE_COLOR:
		{
			red = 1.;
			green = 0.5;
			blue = 0.;
			break;
		}
		case PURPLE_COLOR:
		{
			red = 1.;
			green = 0.;
			blue = 1.;
			break;
		}
		case BROWN_COLOR:
		{
			red = 0.5;
			green = 0.25;
			blue = 0.;
			break;
		}
		default:
		{
			break;
		}
	}
}

///@brief Overload of << operator
///@param s out stream
///@param c RGBcolor to put in the out stream
std::ostream& operator << (std::ostream& s, const RGBcolor& c)
{
	s << c.red << "\t" << c.green << "\t" << c.blue;
	return s;
}

///@brief Overload of == operator : comparison of 2 RGBcolor objects
///@param c1 Left hand operand
///@param c2 Right hand operand
bool operator==(const RGBcolor& c1, const RGBcolor& c2)
{
	if(c1.red != c2.red)
		return false;
	if(c1.green != c2.green)
		return false;
	if(c1.blue != c2.blue)
		return false;
	return true;
}

///@brief Overload of != operator : comparison of 2 RGBcolor objects
///@param c1 Left hand operand
///@param c2 Right hand operand
bool operator!=(const RGBcolor& c1, const RGBcolor& c2)
{
	return !(c1 == c2);
}

///@brief Overload of + operator
///@param c1 Left operand
///@param c2 Right operand
RGBcolor operator+ (const RGBcolor& c1, const RGBcolor& c2)
{
	RGBcolor res;
	res.red = c1.red + c2.red;
	if(res.red > 1.)
		res.red = 1.;
	res.green = c1.green + c2.green;
	if(res.green > 1.)
		res.green = 1.;
	res.blue = c1.blue + c2.blue;
	if(res.blue > 1.)
		res.blue = 1.;
	return res;
}

///@brief Overload of - operator
///@param c1 Left operand
///@param c2 Right operand
RGBcolor operator- (const RGBcolor& c1, const RGBcolor& c2)
{
	RGBcolor res;
	res.red = c1.red - c2.red;
	if(res.red < 0.)
		res.red = 0.;
	res.green = c1.green - c2.green;
	if(res.green < 0.)
		res.green = 0.;
	res.blue = c1.blue - c2.blue;
	if(res.blue < 0.)
		res.blue = 0.;
	return res;
}